"""
视频流API接口
提供视频流获取、截图、录像等功能，以及实时流处理管理
"""
from typing import List, Optional, Dict, Any
from datetime import datetime
from fastapi import APIRouter, HTTPException, Depends, Query, Body
from fastapi.responses import StreamingResponse
import logging

from services.video_processing.video_stream_service import VideoStreamService
from services.video_processing.real_time_stream_pipeline import RealTimeStreamPipeline
from services.core.camera_service import CameraService
from core.deps import get_current_user, get_db
from core.config_manager import get_config_manager
from schemas.user import User
from schemas.video_stream import (
    VideoStreamRequest, VideoStreamResponse, VideoSnapshotRequest, 
    VideoSnapshotResponse, VideoRecordRequest, VideoRecordResponse,
    StreamProtocol, StreamQuality, VideoStreamStatus,
    MultiStreamRequest, MultiStreamResponse, StreamStatistics
)
from sqlalchemy.orm import Session

logger = logging.getLogger(__name__)
router = APIRouter()

# 创建服务实例
video_stream_service = VideoStreamService()
real_time_pipeline = RealTimeStreamPipeline()
config_manager = get_config_manager()


@router.post("/stream", response_model=VideoStreamResponse)
async def get_video_stream(
    request: VideoStreamRequest,
    current_user: User = Depends(get_current_user)
):
    """获取视频流地址"""
    try:
        response = await video_stream_service.get_stream_url(request)
        
        if not response:
            raise HTTPException(status_code=404, detail="无法获取视频流")
        
        return response
        
    except Exception as e:
        logger.error(f"获取视频流失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取视频流失败")


@router.post("/multi-stream", response_model=MultiStreamResponse)
async def get_multi_video_streams(
    request: MultiStreamRequest,
    current_user: User = Depends(get_current_user)
):
    """获取多路视频流地址"""
    try:
        response = await video_stream_service.get_multi_stream_urls(request)
        
        if not response:
            raise HTTPException(status_code=404, detail="无法获取多路视频流")
        
        return response
        
    except Exception as e:
        logger.error(f"获取多路视频流失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取多路视频流失败")


@router.get("/stream/{camera_id}")
async def get_video_stream_simple(
    camera_id: str,
    protocol: StreamProtocol = Query(StreamProtocol.HLS, description="流协议"),
    quality: StreamQuality = Query(StreamQuality.AUTO, description="视频质量"),
    current_user: User = Depends(get_current_user)
):
    """获取视频流地址（简化接口）"""
    try:
        request = VideoStreamRequest(
            camera_id=camera_id,
            protocol=protocol,
            quality=quality
        )
        
        response = await video_stream_service.get_stream_url(request)
        
        if not response:
            raise HTTPException(status_code=404, detail="无法获取视频流")
        
        return response
        
    except Exception as e:
        logger.error(f"获取视频流失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取视频流失败")


@router.get("/status/{camera_id}", response_model=VideoStreamStatus)
async def get_stream_status(
    camera_id: str,
    current_user: User = Depends(get_current_user)
):
    """获取视频流状态"""
    try:
        status = await video_stream_service.get_stream_status(camera_id)
        
        if not status:
            raise HTTPException(status_code=404, detail="摄像头不存在")
        
        return status
        
    except Exception as e:
        logger.error(f"获取流状态失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取流状态失败")


@router.post("/snapshot", response_model=VideoSnapshotResponse)
async def capture_snapshot(
    request: VideoSnapshotRequest,
    current_user: User = Depends(get_current_user)
):
    """捕获视频截图"""
    try:
        response = await video_stream_service.capture_snapshot(request)
        
        if not response:
            raise HTTPException(status_code=404, detail="截图失败")
        
        return response
        
    except Exception as e:
        logger.error(f"截图失败: {str(e)}")
        raise HTTPException(status_code=500, detail="截图失败")


@router.post("/snapshot/{camera_id}")
async def capture_snapshot_simple(
    camera_id: str,
    width: Optional[int] = Query(None, ge=100, le=3840, description="截图宽度"),
    height: Optional[int] = Query(None, ge=100, le=2160, description="截图高度"),
    quality: Optional[int] = Query(90, ge=1, le=100, description="图片质量"),
    current_user: User = Depends(get_current_user)
):
    """捕获视频截图（简化接口）"""
    try:
        request = VideoSnapshotRequest(
            camera_id=camera_id,
            width=width,
            height=height,
            quality=quality
        )
        
        response = await video_stream_service.capture_snapshot(request)
        
        if not response:
            raise HTTPException(status_code=404, detail="截图失败")
        
        return response
        
    except Exception as e:
        logger.error(f"截图失败: {str(e)}")
        raise HTTPException(status_code=500, detail="截图失败")


@router.post("/record", response_model=VideoRecordResponse)
async def get_video_record(
    request: VideoRecordRequest,
    current_user: User = Depends(get_current_user)
):
    """获取录像文件"""
    try:
        response = await video_stream_service.get_video_record(request)
        
        if not response:
            raise HTTPException(status_code=404, detail="获取录像失败")
        
        return response
        
    except Exception as e:
        logger.error(f"获取录像失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取录像失败")


@router.get("/record/{camera_id}")
async def get_video_record_simple(
    camera_id: str,
    start_time: datetime = Query(..., description="开始时间"),
    end_time: datetime = Query(..., description="结束时间"),
    quality: StreamQuality = Query(StreamQuality.AUTO, description="录像质量"),
    current_user: User = Depends(get_current_user)
):
    """获取录像文件（简化接口）"""
    try:
        request = VideoRecordRequest(
            camera_id=camera_id,
            start_time=start_time,
            end_time=end_time,
            quality=quality
        )
        
        response = await video_stream_service.get_video_record(request)
        
        if not response:
            raise HTTPException(status_code=404, detail="获取录像失败")
        
        return response
        
    except Exception as e:
        logger.error(f"获取录像失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取录像失败")


@router.get("/statistics/{camera_id}", response_model=StreamStatistics)
async def get_stream_statistics(
    camera_id: str,
    current_user: User = Depends(get_current_user)
):
    """获取流统计信息"""
    try:
        statistics = await video_stream_service.get_stream_statistics(camera_id)
        
        if not statistics:
            raise HTTPException(status_code=404, detail="统计信息不存在")
        
        return statistics
        
    except Exception as e:
        logger.error(f"获取统计信息失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取统计信息失败")


@router.get("/protocols")
async def get_supported_protocols(
    current_user: User = Depends(get_current_user)
):
    """获取支持的协议列表"""
    try:
        protocols = await video_stream_service.get_supported_protocols()
        return {"protocols": protocols}
        
    except Exception as e:
        logger.error(f"获取协议列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取协议列表失败")


@router.get("/qualities")
async def get_supported_qualities(
    current_user: User = Depends(get_current_user)
):
    """获取支持的质量列表"""
    try:
        qualities = await video_stream_service.get_supported_qualities()
        return {"qualities": qualities}
        
    except Exception as e:
        logger.error(f"获取质量列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取质量列表失败")


@router.delete("/cache")
async def clear_stream_cache(
    camera_id: Optional[str] = Query(None, description="摄像头ID"),
    current_user: User = Depends(get_current_user)
):
    """清除视频流缓存"""
    try:
        await video_stream_service.clear_cache(camera_id)
        
        return {
            "message": f"缓存清除成功: {camera_id or 'all'}"
        }
        
    except Exception as e:
        logger.error(f"清除缓存失败: {str(e)}")
        raise HTTPException(status_code=500, detail="清除缓存失败")


@router.post("/cache/refresh")
async def refresh_stream_cache(
    current_user: User = Depends(get_current_user)
):
    """刷新过期缓存"""
    try:
        await video_stream_service.refresh_stream_cache()
        
        return {"message": "缓存刷新成功"}
        
    except Exception as e:
        logger.error(f"刷新缓存失败: {str(e)}")
        raise HTTPException(status_code=500, detail="刷新缓存失败")


# ==================== 实时流处理管理接口 ====================

@router.post("/real-time/start/{camera_id}")
async def start_real_time_processing(
    camera_id: str,
    current_user: User = Depends(get_current_user)
):
    """启动摄像头实时流处理"""
    try:
        success = await real_time_pipeline.start_camera_stream(camera_id)
        
        if not success:
            raise HTTPException(status_code=400, detail="启动实时流处理失败")
        
        return {
            "message": f"摄像头 {camera_id} 实时流处理已启动",
            "camera_id": camera_id,
            "status": "started"
        }
        
    except Exception as e:
        logger.error(f"启动实时流处理失败: {str(e)}")
        raise HTTPException(status_code=500, detail="启动实时流处理失败")


@router.post("/real-time/stop/{camera_id}")
async def stop_real_time_processing(
    camera_id: str,
    current_user: User = Depends(get_current_user)
):
    """停止摄像头实时流处理"""
    try:
        success = await real_time_pipeline.stop_camera_stream(camera_id)
        
        if not success:
            raise HTTPException(status_code=400, detail="停止实时流处理失败")
        
        return {
            "message": f"摄像头 {camera_id} 实时流处理已停止",
            "camera_id": camera_id,
            "status": "stopped"
        }
        
    except Exception as e:
        logger.error(f"停止实时流处理失败: {str(e)}")
        raise HTTPException(status_code=500, detail="停止实时流处理失败")


@router.post("/real-time/restart/{camera_id}")
async def restart_real_time_processing(
    camera_id: str,
    current_user: User = Depends(get_current_user)
):
    """重启摄像头实时流处理"""
    try:
        success = await real_time_pipeline.restart_camera_stream(camera_id)
        
        if not success:
            raise HTTPException(status_code=400, detail="重启实时流处理失败")
        
        return {
            "message": f"摄像头 {camera_id} 实时流处理已重启",
            "camera_id": camera_id,
            "status": "restarted"
        }
        
    except Exception as e:
        logger.error(f"重启实时流处理失败: {str(e)}")
        raise HTTPException(status_code=500, detail="重启实时流处理失败")


@router.get("/real-time/status/{camera_id}")
async def get_real_time_processing_status(
    camera_id: str,
    current_user: User = Depends(get_current_user)
):
    """获取摄像头实时流处理状态"""
    try:
        status = await real_time_pipeline.get_camera_stream_status(camera_id)
        
        if not status:
            raise HTTPException(status_code=404, detail="摄像头状态不存在")
        
        return status
        
    except Exception as e:
        logger.error(f"获取实时流处理状态失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取实时流处理状态失败")


@router.get("/real-time/status")
async def get_all_real_time_processing_status(
    current_user: User = Depends(get_current_user)
):
    """获取所有摄像头实时流处理状态"""
    try:
        status = await real_time_pipeline.get_all_camera_status()
        
        return {
            "total_cameras": len(status),
            "active_streams": sum(1 for s in status.values() if s.get("status") == "active"),
            "cameras": status
        }
        
    except Exception as e:
        logger.error(f"获取所有实时流处理状态失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取所有实时流处理状态失败")


@router.post("/real-time/batch-start")
async def batch_start_real_time_processing(
    camera_ids: List[str] = Body(..., description="摄像头ID列表"),
    current_user: User = Depends(get_current_user)
):
    """批量启动实时流处理"""
    try:
        results = await real_time_pipeline.batch_start_cameras(camera_ids)
        
        success_count = sum(1 for r in results.values() if r)
        
        return {
            "message": f"批量启动完成，成功 {success_count}/{len(camera_ids)} 个摄像头",
            "results": results,
            "success_count": success_count,
            "total_count": len(camera_ids)
        }
        
    except Exception as e:
        logger.error(f"批量启动实时流处理失败: {str(e)}")
        raise HTTPException(status_code=500, detail="批量启动实时流处理失败")


@router.post("/real-time/batch-stop")
async def batch_stop_real_time_processing(
    camera_ids: List[str] = Body(..., description="摄像头ID列表"),
    current_user: User = Depends(get_current_user)
):
    """批量停止实时流处理"""
    try:
        results = await real_time_pipeline.batch_stop_cameras(camera_ids)
        
        success_count = sum(1 for r in results.values() if r)
        
        return {
            "message": f"批量停止完成，成功 {success_count}/{len(camera_ids)} 个摄像头",
            "results": results,
            "success_count": success_count,
            "total_count": len(camera_ids)
        }
        
    except Exception as e:
        logger.error(f"批量停止实时流处理失败: {str(e)}")
        raise HTTPException(status_code=500, detail="批量停止实时流处理失败")


@router.get("/real-time/performance/{camera_id}")
async def get_camera_performance_metrics(
    camera_id: str,
    current_user: User = Depends(get_current_user)
):
    """获取摄像头性能指标"""
    try:
        metrics = await real_time_pipeline.get_camera_performance_metrics(camera_id)
        
        if not metrics:
            raise HTTPException(status_code=404, detail="性能指标不存在")
        
        return metrics
        
    except Exception as e:
        logger.error(f"获取摄像头性能指标失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取摄像头性能指标失败")


@router.put("/real-time/config/{camera_id}")
async def update_camera_real_time_config(
    camera_id: str,
    config: Dict[str, Any] = Body(..., description="实时处理配置"),
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """更新摄像头实时处理配置"""
    try:
        camera_service = CameraService(db)
        
        # 验证配置
        validation_result = await camera_service.validate_ai_config(int(camera_id), config)
        if not validation_result["valid"]:
            raise HTTPException(
                status_code=400, 
                detail=f"配置验证失败: {', '.join(validation_result['errors'])}"
            )
        
        # 更新配置
        success = await camera_service.update_camera_ai_config(
            int(camera_id), 
            config, 
            current_user.username
        )
        
        if not success:
            raise HTTPException(status_code=400, detail="更新配置失败")
        
        # 如果摄像头正在运行，重启以应用新配置
        if await real_time_pipeline.is_camera_active(camera_id):
            await real_time_pipeline.restart_camera_stream(camera_id)
        
        return {
            "message": f"摄像头 {camera_id} 配置更新成功",
            "camera_id": camera_id,
            "config": config,
            "validation_warnings": validation_result.get("warnings", [])
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新摄像头实时处理配置失败: {str(e)}")
        raise HTTPException(status_code=500, detail="更新摄像头实时处理配置失败")


@router.get("/real-time/config/{camera_id}")
async def get_camera_real_time_config(
    camera_id: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """获取摄像头实时处理配置"""
    try:
        camera_service = CameraService(db)
        config = camera_service.get_camera_ai_config(int(camera_id))
        
        if not config:
            raise HTTPException(status_code=404, detail="摄像头配置不存在")
        
        return config
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取摄像头实时处理配置失败: {str(e)}")
        raise HTTPException(status_code=500, detail="获取摄像头实时处理配置失败")